/*
 * SPDX-License-Identifier: BSD-3-Clause
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
 * Description: virtual dev interface
 * Author: -
 * Create: 2021.4.19
 */

#ifndef UDK_VDEV_H
#define UDK_VDEV_H

#include <sys/queue.h>
#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif

#define UDK_DEV_NAME_MAX_LEN 64

struct udk_vdev_driver;
struct udk_vdev_device {
    TAILQ_ENTRY(udk_vdev_device) next;      /* Next attached vdev */
    char name[UDK_DEV_NAME_MAX_LEN];        /* Name of the device. */
    const struct udk_vdev_driver *driver;   /* Driver assigned after probing */
    int numa_node;                          /* NUMA node connection */
    char *args;
};

/**
 * Probe function called for each virtual device driver once.
 */
typedef int (udk_vdev_probe_t)(struct udk_vdev_device *dev);

/**
 * Remove function called for each virtual device driver once.
 */
typedef int (udk_vdev_remove_t)(struct udk_vdev_device *dev);

struct udk_vdev_driver {
    udk_vdev_probe_t *probe;       /**< Virtual device probe function. */
    udk_vdev_remove_t *remove;     /**< Virtual device remove function. */
};

static inline const char *udk_vdev_device_name(const struct udk_vdev_device *dev)
{
    if (dev != NULL) {
        return dev->name;
    }
    return NULL;
}

static inline const char *udk_vdev_device_args(const struct udk_vdev_device *dev)
{
    if (dev != NULL) {
        return dev->args;
    }
    return "";
}

/**
 * Initialize a driver specified by name.
 *
 * @param name
 *   The pointer to a driver name to be initialized.
 * @param args
 *   The pointer to arguments used by driver initialization.
 * @return
 *  0 on success, negative on error
 */
int udk_vdev_init(const char *name, const char *args, struct udk_vdev_driver *driver);

/**
 * Uninitalize a driver specified by name.
 *
 * @param name
 *   The pointer to a driver name to be uninitialized.
 * @return
 *  0 on success, negative on error
 */
int udk_vdev_uninit(const char *name);
int udk_vdev_is_probed(const struct udk_vdev_device *dev);

#ifdef __cplusplus
}
#endif

#endif